package com.syezon.wifikey.splash.gdt;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.blankj.utilcode.util.ToastUtils;
import com.qq.e.ads.splash.SplashAD;
import com.qq.e.ads.splash.SplashADListener;
import com.qq.e.comm.util.AdError;
import com.syezon.wifikey.BuildConfig;
import com.syezon.wifikey.R;
import com.syezon.wifikey.ad.SDKReportHelper;
import com.syezon.wifikey.config.GDTConfig;
import com.syezon.wifikey.splash.SplashCallBack;
import com.syezon.wifikey.splash.config.SplashConfig;

import butterknife.BindView;
import butterknife.ButterKnife;

public class GdtSplashFragment extends Fragment implements SplashADListener {

    private static final String SPLASH_POS_ID = "gdt_splash_pos_id";


    private SplashAD splashAD;

    private static final String SKIP_TEXT = "点击跳过 %d";

    public boolean canJump = false;

    /**
     * 为防止无广告时造成视觉上类似于"闪退"的情况，设定无广告时页面跳转根据需要延迟一定时间，demo
     * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久，仅供参考，开发者可自定义延时逻辑，如果开发者采用demo
     * 中给出的延时逻辑，也建议开发者考虑自定义minSplashTimeWhenNoAD的值（单位ms）
     **/
    private int minSplashTimeWhenNoAD = 2000;
    /**
     * 记录拉取广告的时间
     */
    private long fetchSplashADTime = 0;
    private Handler handler = new Handler(Looper.getMainLooper());


    @BindView(R.id.view_logo_bottom)
    View mViewBottom;
    @BindView(R.id.fl_container)
    FrameLayout mFlContainer;
    @BindView(R.id.tv_skip)
    TextView mSkipView;
    @BindView(R.id.iv_hold)
    ImageView mIvHold;

    private String mSplashId;

    private boolean mReportShow;

    private SplashCallBack mListener;

    public GdtSplashFragment() {
    }

    public static GdtSplashFragment newInstance(String id) {
        GdtSplashFragment fragment = new GdtSplashFragment();
        Bundle args = new Bundle();
        args.putString(SPLASH_POS_ID, id);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mSplashId = getArguments().getString(SPLASH_POS_ID, "");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.app_splash_fragment_gdt, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);
        init();
    }

    private void init() {
        fetchSplashAD(getActivity(), mFlContainer, mSkipView, GDTConfig.APP_ID, mSplashId, this, 0);
    }

    /**
     * 拉取开屏广告，开屏广告的构造方法有3种，详细说明请参考开发者文档。
     *
     * @param activity      展示广告的activity
     * @param adContainer   展示广告的大容器
     * @param skipContainer 自定义的跳过按钮：传入该view给SDK后，SDK会自动给它绑定点击跳过事件。SkipView的样式可以由开发者自由定制，其尺寸限制请参考activity_splash.xml或者接入文档中的说明。
     * @param appId         应用ID
     * @param posId         广告位ID
     * @param adListener    广告状态监听器
     * @param fetchDelay    拉取广告的超时时长：取值范围[3000, 5000]，设为0表示使用广点通SDK默认的超时时长。
     */
    private void fetchSplashAD(Activity activity, ViewGroup adContainer, View skipContainer,
                               String appId, String posId, SplashADListener adListener, int fetchDelay) {
        fetchSplashADTime = System.currentTimeMillis();
        splashAD = new SplashAD(activity, skipContainer, appId, posId, adListener, fetchDelay);
        splashAD.fetchAndShowIn(adContainer);
        mSkipView.setVisibility(View.GONE);
    }

    @Override
    public void onADPresent() {
        Log.i(GDTConfig.LOG_TAG, "SplashADPresent");
        mIvHold.setVisibility(View.INVISIBLE); // 广告展示后一定要把预设的开屏图片隐藏起来
        mSkipView.setVisibility(View.VISIBLE);
        if (mListener != null) {
            mListener.onLoadSuccess(SplashConfig.SPLASH_AD_SOURCE_GDT);
        }
        if (!mReportShow) {
            mReportShow = true;
            SDKReportHelper.reportSDKAdv(SDKReportHelper.SOURCE_GDT, mSplashId, SDKReportHelper.OP_TYPE_SHOW);
        }
    }

    @Override
    public void onADClicked() {
        Log.i(GDTConfig.LOG_TAG, "SplashADClicked");
        SDKReportHelper.reportSDKAdv(SDKReportHelper.SOURCE_GDT, mSplashId, SDKReportHelper.OP_TYPE_CLICK);
    }

    /**
     * 倒计时回调，返回广告还将被展示的剩余时间。
     * 通过这个接口，开发者可以自行决定是否显示倒计时提示，或者还剩几秒的时候显示倒计时
     *
     * @param millisUntilFinished 剩余毫秒数
     */
    @Override
    public void onADTick(long millisUntilFinished) {
        Log.i(GDTConfig.LOG_TAG, "SplashADTick " + millisUntilFinished + "ms");
        mSkipView.setText(String.format(SKIP_TEXT, Math.round(millisUntilFinished / 1000f)));
    }

    @Override
    public void onADExposure() {
        Log.i(GDTConfig.LOG_TAG, "SplashADExposure");
    }

    @Override
    public void onADLoaded(long l) {
        mIvHold.setVisibility(View.INVISIBLE); // 广告展示后一定要把预设的开屏图片隐藏起来
        mSkipView.setVisibility(View.VISIBLE);
//        splashAD.showAd(mFlContainer);
    }

    @Override
    public void onADDismissed() {
        Log.i(GDTConfig.LOG_TAG, "SplashADDismissed");
        next();
    }

    @Override
    public void onNoAD(AdError error) {
        if (BuildConfig.DEBUG) {
            ToastUtils.showShort(error.getErrorMsg());
        }
        SDKReportHelper.reportSDKAdv(SDKReportHelper.SOURCE_GDT, mSplashId, SDKReportHelper.OP_TYPE_FAIL);
        if (mListener != null) {
            mListener.onLoadFail(SplashConfig.SPLASH_AD_SOURCE_GDT, error.getErrorMsg());
            return;
        }
        Log.i(GDTConfig.LOG_TAG,
                String.format("LoadSplashADFail, eCode=%d, errorMsg=%s", error.getErrorCode(),
                        error.getErrorMsg()));
        /**
         * 为防止无广告时造成视觉上类似于"闪退"的情况，设定无广告时页面跳转根据需要延迟一定时间，demo
         * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久，仅供参考，开发者可自定义延时逻辑，如果开发者采用demo
         * 中给出的延时逻辑，也建议开发者考虑自定义minSplashTimeWhenNoAD的值
         **/
        long alreadyDelayMills = System.currentTimeMillis() - fetchSplashADTime;//从拉广告开始到onNoAD已经消耗了多少时间
        long shouldDelayMills = alreadyDelayMills > minSplashTimeWhenNoAD ? 0 : minSplashTimeWhenNoAD
                - alreadyDelayMills;//为防止加载广告失败后立刻跳离开屏可能造成的视觉上类似于"闪退"的情况，根据设置的minSplashTimeWhenNoAD
        // 计算出还需要延时多久
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mListener != null) {
                    mListener.goMain();
                }
            }
        }, shouldDelayMills);
    }

    /**
     * 设置一个变量来控制当前开屏页面是否可以跳转，当开屏广告为普链类广告时，点击会打开一个广告落地页，此时开发者还不能打开自己的App主页。当从广告落地页返回以后，
     * 才可以跳转到开发者自己的App主页；当开屏广告是App类广告时只会下载App。
     */
    private void next() {
        if (canJump) {
            if (mListener != null) {
                mListener.goMain();
            }
        } else {
            canJump = true;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        canJump = false;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (canJump) {
            next();
        }
        canJump = true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof SplashCallBack) {
            mListener = (SplashCallBack) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement SplashCallBack");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

}
